package com.zhenyi.ayi.index;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.mongodb.morphia.Datastore;

import com.cenjiawen.common.IndexController;
import com.cjw.model.DBMap;
import com.jfinal.aop.Before;
import com.jfinal.aop.Clear;
import com.jfinal.kit.Kv;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;
import com.utils.AESUtils;
import com.utils.AuthUtils;
import com.zhenyi.ayi.interceptor.AuthInterceptor;
import com.zhenyi.ayi.model.Member;
import com.zhenyi.common.model.AyEmployer;
import com.zhenyi.common.model.AyMember;
import com.zhenyi.common.model.AyRegisterInfo;
import com.zhenyi.common.model.AySignInfo;
import com.zhenyi.mongo.core.MongoUtils;
import com.zhenyi.search.SearchResult;
import com.zhenyi.search.SearchUtilsPro;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.RandomUtil;

@Before(AuthInterceptor.class)
public class EditorController extends IndexController {

	private static int pageSize = 10;

	private final String AES_KEY = "beikangayi@#$&*,";

	private final String SEARCH_ENGINE_PATH = "SearchEngine" + File.separatorChar + "beikang";

	private final Integer REGISTER_INFO_SEARCH_TYPE = 0;

	private final Integer MEMBER_SEARCH_TYPE = 1;

	private final Integer EMPLOYER_SEARCH_TYPE = 2;

	private final Integer SIGN_INFO_SEARCH_TYPE = 3;

	@Clear
	public void index() {
		render("/admin/index.html");
	}

	/**
	 * 登录
	 */
	@Clear
	public void login() {
		String account = getPara("account");
		String password = getPara("password");
		try {
			password = AESUtils.decrypt(AES_KEY, password);
			if (password == null) {
				renderFailure();
				return;
			}
		} catch (Exception e) {
			renderFailure();
			return;
		}

		String defAccount = PropKit.get("BK_ADMIN_USER", "admin");
		String defPassword = PropKit.get("BK_ADMIN_PASSWORD", "beikang");
		if (!StrKit.notBlank(defAccount, defPassword)) {
			renderFailure(500, "账号或密码不正确");
			return;
		}
		if (!defAccount.equals(account)) {
			renderFailure(500, "账号或密码不正确.");
			return;
		}
		if (!defPassword.equals(password)) {
			renderFailure(500, "账号或密码不正确 .");
			return;
		}
		String token = AuthUtils.login(account, this);
		renderSuccess(token);
	}

	public void logout() {
		renderFlag(AuthUtils.logout(this));
	}

	public void registerInfoList() {
		SqlPara sqlPara = Db.getSqlPara("FindRegisterInfo");
		Page<Record> items = Db.paginate(getPage(), pageSize, sqlPara);
		renderPage(items);
	}

	public void registerInfo() {
		Long id = getParaToLong("id");
		AyRegisterInfo info = AyRegisterInfo.dao.findById(id);
		renderSuccess(info);
	}

	public void submitRegisterInfo() {
		Long id = getParaToLong("id");
		AyRegisterInfo info = id == null ? new AyRegisterInfo() : AyRegisterInfo.dao.findById(id);
		String[] keys = { "no", "image", "name", "age", "birth", "idcard", "jiguan", "degree", "liveAddress", "channel",
				"type", "cert", "contact", "desc", "images", "height", "weight", "content", "train", "title", "sort",
				"salary", "cover", "tags", "constellation" };
		for (String key : keys) {
			String value = getPara(key);
			if (StrKit.isBlank(key)) {
				continue;
			}
			info.set(key, value);
		}
		boolean flag = false;
		if (info.getId() == null) {
			flag = info.save();
		} else {
			flag = info.update();
		}
		if (flag) {
			try {
				SearchUtilsPro searchUtils = new SearchUtilsPro(SEARCH_ENGINE_PATH);
				HashMap<String, String> fields = new HashMap<>();
				for (String key : keys) {
					if (key.equals("name"))
						continue;
					if (info.get(key) != null && !info.get(key).equals("")) {
						fields.put(key, info.get(key));
					}
				}
				searchUtils.add(info.getId(), info.getName(), REGISTER_INFO_SEARCH_TYPE, null, fields);
			} catch (Exception e) {
				e.printStackTrace();
				renderFailure();
			}
			renderSuccess();
		} else {
			renderFailure();
		}
	}

	public void deleteRegisterInfo() {
		Long id = getParaToLong("id");
		AyRegisterInfo info = AyRegisterInfo.dao.findById(id);
		boolean flag = info.delete();
		if (flag) {
			SearchUtilsPro searchUtils = new SearchUtilsPro(SEARCH_ENGINE_PATH);
			try {
				searchUtils.remove(info.getId());
				renderSuccess();
			} catch (IOException | ParseException e) {
				renderFailure();
				e.printStackTrace();
			}
		} else {
			renderFailure();
		}
	}

	public void searchRegisterInfo() {
		String keyword = getPara("keyword", "");
		String[] fields = { "no", "image", "name", "age", "birth", "idcard", "jiguan", "degree", "liveAddress",
				"channel", "type", "cert", "contact", "desc", "images", "height", "weight", "content", "train", "title",
				"sort", "salary", "cover", "tags", "constellation" };
		search(keyword, REGISTER_INFO_SEARCH_TYPE, fields, getPage());
	}

	public void memberList() {
		SqlPara sqlPara = Db.getSqlPara("FindMember");
		Page<Record> items = Db.paginate(getPage(), pageSize, sqlPara);
		renderPage(items);
	}

	public void member() {
		Long id = getParaToLong("id");
		AyMember info = AyMember.dao.findById(id);
		renderSuccess(info);
	}

	public void submitMember() {
		Long id = getParaToLong("id");
		AyMember info = id == null ? new AyMember() : AyMember.dao.findById(id);
		String[] keys = { "no", "image", "name", "age", "birth", "idcard", "jiguan", "degree", "liveAddress", "channel",
				"type", "cert", "contact", "desc", "images", "height", "weight", "content", "train", "title", "sort",
				"salary", "cover", "tags", "constellation" };
		for (String key : keys) {
			String value = getPara(key);
			if (StrKit.isBlank(key)) {
				continue;
			}
			info.set(key, value);
		}
		boolean flag = false;
		if (info.getId() == null) {
			flag = info.save();
		} else {
			flag = info.update();
		}
		if (flag) {
			try {
				SearchUtilsPro searchUtils = new SearchUtilsPro(SEARCH_ENGINE_PATH);
				HashMap<String, String> fields = new HashMap<>();
				for (String key : keys) {
					if (key.equals("name"))
						continue;
					if (info.get(key) != null && !info.get(key).equals("")) {
						fields.put(key, info.get(key));
					}
				}
				searchUtils.add(info.getId(), info.getName(), MEMBER_SEARCH_TYPE, null, fields);
			} catch (Exception e) {
				e.printStackTrace();
				renderFailure();
			}
			renderSuccess();
		} else {
			renderFailure();
		}
	}

	public void deleteMember() {
		Long id = getParaToLong("id");
		AyMember info = AyMember.dao.findById(id);
		boolean flag = info.delete();
		if (flag) {
			SearchUtilsPro searchUtils = new SearchUtilsPro(SEARCH_ENGINE_PATH);
			try {
				searchUtils.remove(info.getId());
				renderSuccess();
			} catch (IOException | ParseException e) {
				renderFailure();
				e.printStackTrace();
			}
		} else {
			renderFailure();
		}
	}

	public void searchMember() {
		String keyword = getPara("keyword", "");
		String[] fields = { "no", "image", "name", "age", "birth", "idcard", "jiguan", "degree", "liveAddress",
				"channel", "type", "cert", "contact", "desc", "images", "height", "weight", "content", "train", "title",
				"sort", "salary", "cover", "tags", "constellation" };
		search(keyword, MEMBER_SEARCH_TYPE, fields, getPage());
	}

	public void employerList() {
		SqlPara sqlPara = Db.getSqlPara("FindEmployer");
		Page<Record> items = Db.paginate(getPage(), pageSize, sqlPara);
		renderPage(items);
	}

	public void employer() {
		Long id = getParaToLong("id");
		AyEmployer info = AyEmployer.dao.findById(id);
		renderSuccess(info);
	}

	public void submitEmployer() {
		Long id = getParaToLong("id");
		AyEmployer info = id == null ? new AyEmployer() : AyEmployer.dao.findById(id);
		String[] keys = { "no", "name", "idcard", "babyBirth", "city", "date", "source", "liveAddress", "type",
				"contact", "", "", "" };
		for (String key : keys) {
			String value = getPara(key);
			if (StrKit.isBlank(key)) {
				continue;
			}
			info.set(key, value);
		}
		boolean flag = false;
		if (info.getId() == null) {
			flag = info.save();
		} else {
			flag = info.update();
		}
		if (flag) {
			try {
				SearchUtilsPro searchUtils = new SearchUtilsPro(SEARCH_ENGINE_PATH);
				HashMap<String, String> fields = new HashMap<>();
				for (String key : keys) {
					if (key.equals("name"))
						continue;
					if (info.get(key) != null && !info.get(key).equals("")) {
						fields.put(key, info.get(key));
					}
				}
				searchUtils.add(info.getId(), info.getName(), EMPLOYER_SEARCH_TYPE, null, fields);
			} catch (Exception e) {
				e.printStackTrace();
				renderFailure();
			}
			renderSuccess();
		} else {
			renderFailure();
		}
	}

	public void deleteEmployer() {
		Long id = getParaToLong("id");
		AyEmployer info = AyEmployer.dao.findById(id);
		boolean flag = info.delete();
		if (flag) {
			SearchUtilsPro searchUtils = new SearchUtilsPro(SEARCH_ENGINE_PATH);
			try {
				searchUtils.remove(info.getId());
				renderSuccess();
			} catch (IOException | ParseException e) {
				renderFailure();
				e.printStackTrace();
			}
		} else {
			renderFailure();
		}
	}

	public void searchEmployer() {
		String keyword = getPara("keyword", "");
		String[] fields = { "no", "name", "idcard", "babyBirth", "city", "date", "source", "liveAddress", "type",
				"contact" };
		search(keyword, EMPLOYER_SEARCH_TYPE, fields, getPage());
	}

	public void signInfoList() {
		SqlPara sqlPara = Db.getSqlPara("FindSignInfo");
		Page<Record> items = Db.paginate(getPage(), pageSize, sqlPara);
		renderPage(items);
	}

	public void signInfo() {
		Long id = getParaToLong("id");
		AySignInfo info = AySignInfo.dao.findById(id);
		renderSuccess(info);
	}

	public void submitSignInfo() {
		Long id = getParaToLong("id");
		AySignInfo info = id == null ? new AySignInfo() : AySignInfo.dao.findById(id);
		String[] keys = { "no", "name", "employer", "city", "shop", "type", "mobile" };
		for (String key : keys) {
			String value = getPara(key);
			if (StrKit.isBlank(key)) {
				continue;
			}
			info.set(key, value);
		}
		boolean flag = false;
		if (info.getId() == null) {
			flag = info.save();
		} else {
			flag = info.update();
		}
		if (flag) {
			try {
				SearchUtilsPro searchUtils = new SearchUtilsPro(SEARCH_ENGINE_PATH);
				HashMap<String, String> fields = new HashMap<>();
				for (String key : keys) {
					if (key.equals("name"))
						continue;
					if (info.get(key) != null && !info.get(key).equals("")) {
						fields.put(key, info.get(key));
					}
				}
				searchUtils.add(info.getId(), info.getName(), SIGN_INFO_SEARCH_TYPE, null, fields);
			} catch (Exception e) {
				e.printStackTrace();
				renderFailure();
			}
			renderSuccess();
		} else {
			renderFailure();
		}
	}

	public void deleteSignInfo() {
		Long id = getParaToLong("id");
		AySignInfo info = AySignInfo.dao.findById(id);
		boolean flag = info.delete();
		if (flag) {
			SearchUtilsPro searchUtils = new SearchUtilsPro(SEARCH_ENGINE_PATH);
			try {
				searchUtils.remove(info.getId());
				renderSuccess();
			} catch (IOException | ParseException e) {
				renderFailure();
				e.printStackTrace();
			}
		} else {
			renderFailure();
		}
	}

	public void searchSignInfo() {
		String keyword = getPara("keyword", "");
		String[] fields = { "no", "name", "employer", "city", "shop", "type", "mobile" };
		search(keyword, SIGN_INFO_SEARCH_TYPE, fields, getPage());
	}

	@SuppressWarnings("unchecked")
	private void search(String keyword, Integer type, String[] fields, int pageIndex) {
		SearchUtilsPro searchUtils = new SearchUtilsPro(SEARCH_ENGINE_PATH);
		try {
			HashMap<String, Object> items = searchUtils.search(keyword, type, fields, pageIndex, pageSize);
			ArrayList<SearchResult> list = (ArrayList<SearchResult>) items.get("results");
			List<Record> result = new ArrayList<>();
			if (list.size() > 0) {
				ArrayList<Long> idList = new ArrayList<>();
				for (SearchResult sr : list) {
					idList.add(sr.getId());
				}
				Long[] ids = ArrayUtil.toArray(idList, Long.class);
				SqlPara sqlPara;
				if (type.equals(REGISTER_INFO_SEARCH_TYPE)) {
					sqlPara = Db.getSqlPara("FindRegisterInfoByIds", Kv.by("ids", ids));
				} else if (type.equals(MEMBER_SEARCH_TYPE)) {
					sqlPara = Db.getSqlPara("FindMemberByIds", Kv.by("ids", ids));
				} else if (type.equals(EMPLOYER_SEARCH_TYPE)) {
					sqlPara = Db.getSqlPara("FindEmployerByIds", Kv.by("ids", ids));
				} else if (type.equals(SIGN_INFO_SEARCH_TYPE)) {
					sqlPara = Db.getSqlPara("FindSignInfoByIds", Kv.by("ids", ids));
				} else {
					renderFailure();
					return;
				}
				result = Db.find(sqlPara);
			}
			DBMap map = new DBMap();
			Integer status = 200;
			map.put("info", result);
			map.put("status", status);
			map.put("msg", "ok");
			map.put("page", pageIndex);
			map.put("size", pageSize);
			map.put("total", items.get("totalPage"));

			setAttr("status", status);
			setAttr("msg", "ok");
			setAttr("page", pageIndex);
			setAttr("size", pageSize);
			setAttr("total", items.get("totalPage"));

			renderJson(map);

		} catch (IOException | ParseException | InvalidTokenOffsetsException e) {
			renderFailure();
			e.printStackTrace();
		}
	}

	public void updateStaff() {
		Datastore data = MongoUtils.getInstance().getDB();

		// Activity activity = new Activity();
		// activity.setTitle("act");
		// data.save(activity);

		for (int i = 10000; i < 10007; i++) {
			String img = "https://tva1.sinaimg.cn/crop.107.20.332.332.180/6b57de11gw1enhnf5qp8ij20c80c8767.jpg";
			Member member = new Member();
			member.setName("阿姨" + RandomUtil.randomString(4));
			member.setImage(img);
			member.setNo(String.valueOf(RandomUtil.randomInt(10000, 20000)));
			member.setAge(String.valueOf(RandomUtil.randomInt(18, 50)));
			member.setBirth(
					RandomUtil.randomInt(1960, 1990) + "0" + RandomUtil.randomInt(1, 9) + RandomUtil.randomInt(1, 28));
			member.setIdcard("44030" + RandomUtil.randomInt(10000, 20000));
			member.setJiguan("广东");
			member.setLiveAddress("广东省香洲区");
			member.setChannel("渠道");
			member.setType("兼职");
			member.setCert("美国证书");
			member.setContact("电话号码133928887777");
			member.setAddTime(new Date());
			member.setDesc("阿姨是一个很厉害的阿姨");
			member.setDegree("大学");
			member.setContent(
					"官方 Java 驱动程序可用于与 MongoDB 交互。该驱动程序提供 Map 的实现 BasicDBObject，用于在数据存储中表示文档。虽然Map 表示法很方便，尤其是在读对 JSON 序列化和反序列化时，但是能够将文档表示为 Java 类层次也具有其优点。例如，反复从 Java 域模型映射文档，允许您在 Java 层上强行执行类型安全，同时通过 MongoDB 享受无模式（schema）开发的好处。");
			member.setHeight(String.valueOf(RandomUtil.randomInt(150, 180)));
			member.setWeigth(String.valueOf(RandomUtil.randomInt(40, 80)));
			member.setTrain(
					"Morphia 是基于 Apache 许可证的 Google Code 项目，让您在 MongoDB 上持久保存、检索、删除和查询作为文档存储的 POJO。通过提供一系列围绕 Mongo Java 驱动程序的注释和包装程序，Morphia 完成了这些操作。Morphia 概念上类似于对象关系映射器（ORM），如 Java Persistence API (JPA) 或 Java 数据对象（Java Data Objects，JDO）实现。");
			member.setTitle("高级护理师");
			ArrayList<String> images = new ArrayList<>();
			images.add("https://wx2.sinaimg.cn/mw690/b7cd25aely1ftv216dm32j20k00mbmzj.jpg");
			images.add("https://wx2.sinaimg.cn/mw690/6628f9e0gy1ftuk1itai2j20k00qojv5.jpg");
			images.add("https://wx2.sinaimg.cn/mw690/60718250ly1ftvfvi6fo8j2074074jrk.jpg");
			images.add("https://wx2.sinaimg.cn/mw690/60718250ly1ftvfcqu8g5j20go0go43l.jpg");
			member.setImages(images);
			data.save(member);

		}
		renderSuccess();
	}
}
